﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace StressTestEchoServer
{
	public class UDPEchoServer
	{
		private int port = 0;
		private Thread thread = null;
		private Boolean isRunning;

		public UDPEchoServer(int port)
		{
			if (port < 1024)
				throw new Exception("Ungültiger Port!");

			this.port = port;
			this.isRunning = false;
		}

		public Boolean IsRunning
		{
			get { return this.isRunning; }
		}

		/// <summary>
		/// Stopt den TCPEchoServer
		/// </summary>
		public void StopServer()
		{
			this.isRunning = false;

			if (!thread.Equals(null))
			{
				if (thread.IsAlive)
					thread.Abort();

				thread = null;
			}
		}

		/// <summary>
		/// Startet den TCPEchoServer
		/// </summary>
		public void StartServer()
		{
			if (port < 1024)
				throw new Exception("Ungültiger Port!");

			isRunning = true;
			thread = new Thread(this.Echo);
			thread.Start();

            this.Output();
		}

        public void Output()
        {
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("UDPEchoServer auf Port {0} gestartet!", port);
            Console.WriteLine("Folgende Adressen wurden gefunden:");
            IPHostEntry Host = Dns.GetHostEntry(Dns.GetHostName());

            foreach (IPAddress ipAddress in Host.AddressList)
                //Abfrage ob Adresse = IPv4
                if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
                    Console.WriteLine(ipAddress.ToString());
            Console.WriteLine("--------------------------------------");
        }

		/// <summary>
		/// Wartet auf eine Verbindungen von einem Client und
		/// und sendet die Daten von dem Client wieder zurück
		/// </summary>
		private void Echo()
		{
			UdpClient socketServer = new UdpClient(port);

			IPEndPoint client = new IPEndPoint(IPAddress.Any, port);

			while (isRunning)
			{
				if (socketServer.Available > 0)
				{
                    try
                    {
                        byte[] data = socketServer.Receive(ref client);

                        Console.WriteLine("{0} Daten von {1}:{2} erhalten!", data.Length, client.Address, client.Port);
                        socketServer.Send(data, data.Length, client);

                    }catch(SocketException e)
                    {
                        client = new IPEndPoint(IPAddress.Any, port);
                    }

				}
				else
					Thread.Sleep(1);
			}

			socketServer.Close();
		}
	}
}
